﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace ICalendar.CalendarProperties
{
    /// <summary>
    /// This property specifies information related to the global position for the activity specified by a calendar component.
    /// </summary>
    /// <remarks>
    /// The property value specifies latitude and longitude, in that order (i.e., "LAT LON" ordering). The longitude represents the location east or west of the prime meridian as a positive or negative real number, respectively. The longitude and latitude values MAY be specified up to six decimal places, which will allow for accuracy to within one meter of geographical position. Receiving applications MUST accept values of this precision and MAY truncate values of greater precision.
    ///
    ///  Values for latitude and longitude shall be expressed as decimal fractions of degrees. Whole degrees of latitude shall be represented by a two-digit decimal number ranging from 0 through 90. Whole degrees of longitude shall be represented by a decimal number ranging from 0 through 180. When a decimal fraction of a degree is specified, it shall be separated from the whole number of degrees by a decimal point.
    /// 
    /// Latitudes north of the equator shall be specified by a plus sign (+), or by the absence of a minus sign (-), preceding the digits designating degrees. Latitudes south of the Equator shall be designated by a minus sign (-) preceding the digits designating degrees. A point on the Equator shall be assigned to the Northern Hemisphere.
    /// 
    /// Longitudes east of the prime meridian shall be specified by a plus sign (+), or by the absence of a minus sign (-), preceding the digits designating degrees. Longitudes west of the meridian shall be designated by minus sign (-) preceding the digits designating degrees. A point on the prime meridian shall be assigned to the Eastern Hemisphere. A point on the 180th meridian shall be assigned to the Western Hemisphere. One exception to this last convention is permitted. For the special condition of describing a band of latitude around the earth, the East Bounding Coordinate data element shall be assigned the value +180 (180) degrees.
    /// 
    /// Any spatial address with a latitude of +90 (90) or -90 degrees will specify the position at the North or South Pole, respectively. The component for longitude may have any legal value.
    /// 
    /// With the exception of the special condition described above, this form is specified in Department of Commerce, 1986, Representation of geographic point locations for information interchange (Federal Information Processing Standard 70-1): Washington, Department of Commerce, National Institute of Standards and Technology.
    /// 
    /// The simple formula for converting degrees-minutes-seconds into decimal degrees is:
    /// 
    /// decimal = degrees + minutes/60 + seconds/3600.
    /// </remarks>
    [XmlRoot("geo")]
    [Serializable]
    public class Geo : CalendarPropertyBase<float[]>
    {

        public float Latitude { get; set; }
        public float Longitude { get; set; }

        public Geo()
        {
            this.Value = new float[2];
        }

        public Geo(float latitude, float longitude)
        {
            this.Latitude = latitude;
            this.Longitude = longitude;
            this.Value = new[] {latitude, longitude};
        }

        public override float[] Value
        {
            get { return new[] { Latitude, Longitude }; }
            set
            {
                if (value.GetUpperBound(0) == 1)
                {
                    Latitude = value[0];
                    Longitude = value[1];
                }
                else throw new ArgumentOutOfRangeException("value", "The value must have two elements.");
            }
        }

        protected override void SetValue(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                Value = new float[2];
                return;
            }
            var values = value.Split(';');
            if (values.GetUpperBound(0) >= 0)
            {
                Latitude = Convert.ToSingle(values[0]);
            }
            if (values.GetUpperBound(1) >= 1)
            {
                Longitude = Convert.ToSingle(values[1]);
            }
        }

        protected override string GetValue()
        {
            var cultureInfo = CultureInfo.CreateSpecificCulture("en-US");
            return string.Format("{0};{1}", Latitude.ToString(cultureInfo), Longitude.ToString(cultureInfo));
        }

        protected override void SetParametersFromXParameters(XParameterCollection xparams)
        {
            
        }

        protected override XParameterCollection GetXParametersFromParameters()
        {
            return null;
        }

        protected override string[] GetXReservedParametersNames()
        {
            return null;
        }

        public float ConvertFromDegrees(float degrees, int minutes, int seconds)
        {
            return degrees + minutes/60f + seconds/3600f;
        }
      
    }
}